﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DiscoveryLogic.Analytics.BusinessLogic.Importers;
using DiscoveryLogic.Analytics.BusinessLogic.Networks;
using DiscoveryLogic.Analytics.DataObjects;
using DiscoveryLogic.Analytics.DataObjects.Networks;
using DiscoveryLogic.Common.Utilities;
using DiscoveryLogic.Common.Utilities.OpenXml;
using MessageBox=System.Windows.MessageBox;
using UserControl=System.Windows.Controls.UserControl;

namespace DiscoveryLogic.Analytics.Modules.DataImport
{
    /// <summary>
    /// Interaction logic for PubImporter.xaml
    /// </summary>
    public partial class PubImporter : UserControl
    {
        public delegate void OnDataImported(string networkName);
        public event OnDataImported DataImported;

        public delegate void OnStatusChanged(string msg, int pct);
        public event OnStatusChanged StatusChanged;
        private BackgroundWorker bgWorker;
        private string _NetworkName;
        private class BgArgument
        {
            private bool _AddToExistingNetwork;
            /// <summary></summary>
            public bool AddToExistingNetwork
            {
                get
                {
                    return this._AddToExistingNetwork;
                }
                set
                {
                    this._AddToExistingNetwork = value;
                }
            }

            private List<int> _PMIDs;
            /// <summary></summary>
            public List<int> PMIDs
            {
                get
                {
                    return this._PMIDs;
                }
                set
                {
                    this._PMIDs = value;
                }
            }

            private List<int> _WosItemIDs;
            /// <summary></summary>
            public List<int> WosItemIDs
            {
                get
                {
                    return this._WosItemIDs;
                }
                set
                {
                    this._WosItemIDs = value;
                }
            }
        }

        public PubImporter()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.cboExistNetworks.Items.Clear();
            List<string> networkNames = NetworkManager.GetAllNetworkNames();
            foreach(string networkname in networkNames)
            {
                this.cboExistNetworks.Items.Add(networkname);
            }
            this.rdPMID.IsChecked = true;
            this.rdWosID.IsChecked = false;
        }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            BgArgument args = new BgArgument();
            args.AddToExistingNetwork = false;
            if (this.rdExist.IsChecked.Value)
            {
                args.AddToExistingNetwork = true;
                this._NetworkName = this.cboExistNetworks.SelectedItem.ToString();
            }
            else
            {
                this._NetworkName = this.txtNetworkName.Text;
            }
            if (this.rdPMID.IsChecked.Value)
            {
                args.PMIDs = new List<int>();
                string[] pmidItems = this.txtKeys.Text.Split(new char[] { '\n', '\r' });
                foreach (string pmidStr in pmidItems)
                {
                    if (!string.IsNullOrEmpty(pmidStr.Trim()))
                    {
                        int pmid = int.Parse(pmidStr.Trim());
                        args.PMIDs.Add(pmid);
                    }
                }
            }
            else
            {
                args.WosItemIDs = new List<int>();
                string[] itemStrs = this.txtKeys.Text.Split(new char[] { '\n', '\r' });
                foreach (string itemStr in itemStrs)
                {
                    if (!string.IsNullOrEmpty(itemStr.Trim()))
                    {
                        int wosId = int.Parse(itemStr.Trim());
                        args.WosItemIDs.Add(wosId);
                    }
                }
            }

            this.bgWorker = new BackgroundWorker();
            this.bgWorker.WorkerReportsProgress = true;
            this.bgWorker.WorkerSupportsCancellation = true;
            this.bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged);
            this.bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
            this.bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);

            this.bgWorker.RunWorkerAsync(args);
        }


        void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                this.bgWorker.ReportProgress(10, "Retrieving publications from database...");
                BgArgument args = (BgArgument) e.Argument;
                List<PublicationDO> pubs = null;
                if (args.PMIDs != null && args.PMIDs.Count > 0)
                {
                    pubs = PubImportUtil.GetPublicationsByPMID(args.PMIDs);
                }
                else
                {
                    pubs = PubImportUtil.GetPublicationsByWosItemIDs(args.WosItemIDs);
                }

                List<EntityBase> entities = new List<EntityBase>();
                if (pubs != null && pubs.Count > 0)
                {
                    foreach (PublicationDO pub in pubs)
                        entities.Add(pub);
                }
                if (args.AddToExistingNetwork)
                {
                    Network network = Network.Read(this._NetworkName);
                    network.Records.AddRange(entities);
                    network.Save();
                }
                else
                {
                    Network network = new Network(this._NetworkName, entities, new List<Link>());
                    network.Save();
                }
                this.bgWorker.ReportProgress(0, "Done");
            }
            catch(Exception ex)
            {
                ExceptionHandler.HandlesException(ex);
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }

        void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (this.DataImported != null)
                this.DataImported(this._NetworkName);

            if(this.Parent is Window)
            {
                ((Window)this.Parent).Close();
            }
        }

        void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (this.StatusChanged != null)
                this.StatusChanged(e.UserState.ToString(), e.ProgressPercentage);
        }

        private void rdNew_Checked(object sender, RoutedEventArgs e)
        {
            if(!this.IsInitialized)
                return;
            if(this.rdNew.IsChecked.Value)
            {
                this.rdExist.IsChecked = false;
                this.txtNetworkName.IsEnabled = true;
                this.cboExistNetworks.IsEnabled = false;
            }
            else
            {
                this.rdExist.IsChecked = true;
                this.txtNetworkName.IsEnabled = false;
                this.cboExistNetworks.IsEnabled = true;
            }
        }

        private void rdExist_Checked(object sender, RoutedEventArgs e)
        {
            if (!this.IsInitialized)
                return;
            if (!this.rdExist.IsChecked.Value)
            {
                this.rdExist.IsChecked = false;
                this.txtNetworkName.IsEnabled = true;
                this.cboExistNetworks.IsEnabled = false;
            }
            else
            {
                this.rdExist.IsChecked = true;
                this.txtNetworkName.IsEnabled = false;
                this.cboExistNetworks.IsEnabled = true;
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            if (this.Parent is Window)
            {
                ((Window)this.Parent).Close();
            }
        }

    }
}
